/**
 * @file
 * @brief	Declares the intersection parameters classes.
 */
#ifndef GST_IntersectionParameters_h__
#define GST_IntersectionParameters_h__

#include "buildspec.h"

#include <string>
#include "Client/ClientUtils/MoMaStructs.h"

namespace GST
{
namespace ClientUtils
{
class AbstractRDBAccess;
class PgAccess;
class OCcciAccess;

namespace MapImageDirection
{
/**
 * @brief	left or right Direction.
 *
 * @see		MapImageParameters::direction
 */
enum Direction
{
	left = 1,
	right = -1
};
};

/**
 * @brief	Defines a range of z values.
 */
class GST_API_EXPORT DepthRange
{
public:
	/**
	 * @brief	Default constructor.
	 *
	 * Sets the range to default ([-maxDoubleValue,maxDoubleValue])
	 */
	DepthRange();

	/**
	 * @brief	Set zmin to a specific value.
	 *
	 * @throws GSTInvalidArgument if zmin >= zmax
	 */
	DepthRange &zmin(double zmin);

	/**
	 * @brief	Set zmax to a specific value.
	 *
	 * @throws GSTInvalidArgument if zmax <= zmin
	 */
	DepthRange &zmax(double zmax);

	/**
	 * @brief	Gets the zmin.
	 *
	 * @return	The zmin.
	 */
	double getZmin() const;

	/**
	 * @brief	Gets the zmax.
	 *
	 * @return	The zmax.
	 */
	double getZmax() const;

private:
	double mZmin;
	double mZmax;
};

/**
 * @brief	Defines a distance value. (>= 0.)
 */

class GST_API_EXPORT Distance
{
public:
	/**
	 * @brief	Default constructor.
	 *
	 * Sets value to the default (0.)
	 */
	Distance();

	/**
	 * @brief	Constructor.
	 *
	 * Sets the distance to value.
	 *
	 * @throws GSTInvalidArgument if value < 0.
	 */
	Distance(double value);

	/**
	 * @brief	Gets the value.
	 *
	 * @return	The value.
	 */
	double getValue() const;

	/**
	 * @brief	Set distance to the minimum value (0.).
	 *
	 */
	Distance &min();

	/**
	 * @brief	Set distance to the maximum value (maxDoubleValue).
	 */
	Distance &max();

private:
	double mValue;
};

/**
 * @brief	Defines a dip value ( [0.,90.] )
 */
class GST_API_EXPORT Dip
{
public:
	/**
	 * @brief	Default constructor.
	 *
	 * Sets the value to the default (90.)
	 */
	Dip();

	/**
	 * @brief	Constructor.
	 *
	 * Sets the dip to value.
	 *
	 * @param	value	The value.
	 *
	 * @throws GSTInvalidArgument if value < 0. or value > 90.
	 */
	Dip(double value);

	/**
	 * @brief	Gets the value.
	 *
	 * @return	The value.
	 */
	double getValue() const;

private:
	double mValue;
};

/**
 * @brief	Defines an azimuth value ( [0.,360.) )
 */
class GST_API_EXPORT Azimuth
{
public:
	/**
	 * @brief	Default constructor.
	 *
	 * Sets the value to the default (0.)
	 */
	Azimuth();
	/**
	 * @brief	Constructor.
	 *
	 * Sets the azimuth to value.
	 *
	 * @param	value	The value.
	 *
	 * @throws GSTInvalidArgument if value < 0. or value > 360.
	 */
	Azimuth(double value);

	/**
	 * @brief	Gets the value.
	 *
	 * @return	The value.
	 */
	double getValue() const;

private:
	double mValue;
};

/**
 * @brief	Defines a property selection parameter
 */
struct GST_API_EXPORT PropertySelection
{
	/**
	 * @brief	Name of the property.
	 */
	std::string propertyName;

	/**
	 * @brief	Identifier for the color map.
	 */
	ColorMap::Id colorMapId;

	/**
	 * @brief	Default constructor.
	 */
	PropertySelection();

	/**
	 * @brief	Constructor.
	 *
	 * @param	propertyName	Name of the property.
	 * @param	colorMapId  	Identifier for the color map.
	 */
	PropertySelection(const std::string &propertyName, ColorMap::Id colorMapId);
};

/**
 * @brief	Defines a scale parameter in 1 dimension
 */
class GST_API_EXPORT ScaleParameter1D
{
public:
	/**
	 * @brief	Default constructor.
	 *
	 * Sets value to default (auto compute)
	 */
	ScaleParameter1D();

	/**
	 * @brief	Constructor.
	 *
	 * Sets the scale parameter to value\n
	 * values <= 0 mean auto compute\n
	 * values > 0 mean use this exact scale parameter
	 */
	ScaleParameter1D(long value);

	/**
	 * @brief	Gets the value.
	 *
	 * @return	The value.
	 */
	long getValue() const;

private:
	long mValue;
};

/**
 * @brief	Defines a scale parameter in 2 dimension
 */
class GST_API_EXPORT ScaleParameter2D
{
public:
	/**
	 * @brief	Default constructor.
	 *
	 * 	Sets the values to default (auto compute)
	 */
	ScaleParameter2D();

	/**
	 * @brief	Set the xScale to value
	 *
	 * values <= 0 mean auto compute\n
	 * values > 0 mean use this exact scale parameter
	 */
	ScaleParameter2D &xScale(long xScale);
	/**
	 * @brief	Set the vertical exaggeration to value
	 *
	 * values <= 0 mean auto compute\n
	 * values > 0 mean use this exact scale parameter
	 */
	ScaleParameter2D &verticalExaggeration(double verticalExaggeration);

	/**
	 * @brief	Get x coordinate scale.
	 *
	 * @return	The x coordinate scale.
	 */
	long getXScale() const;

	/**
	 * @brief	Gets vertical exaggeration.
	 *
	 * @return	The vertical exaggeration.
	 */
	double getVerticalExaggeration() const;

private:
	long mXScale;
	double mVerticalExaggeration;
};

/**
 * @brief	Makes a ScaleParameter1D from a ScaleParameter2D
 *
 * @param	param	The 2d scale parameter.
 *
 * @return	A ScaleParameter1D.
 */
ScaleParameter1D makeScaleParameter1D(const ScaleParameter2D &param);

/**
 * @brief	Sets the parameters for the resulting shapefile(s)
 */
class GST_API_EXPORT OutputShapeParameters
{
public:
	/**
	 * @brief	Constructor.
	 *
	 * @param	outputPath  	Full pathname of the output file.
	 */
	OutputShapeParameters(const std::string &outputPath)
			: m_outputPath(outputPath)
			, m_verticalExaggeration(1.)
			, m_title()
			, m_jsonConfig()
			, m_inProfileCoordinates(false)
	{
	}
	const std::string &getOutputPath() const
	{
		return m_outputPath;
	}

	/**
	 * @brief	set a title for the shapefile
	 *
	 * @param	title of the shapefile
	 */
	OutputShapeParameters &title(const std::string &title)
	{
		m_title = title;
		return *this;
	}
	const std::string &getTitle() const
	{
		return m_title;
	}

	/**
	 * @brief	set json config for the shapefile
	 *
	 * @param	json encoded string of config for the shapefile
	 */
	OutputShapeParameters &jsonConfig(
			const std::string &jsonConfig)
	{
		m_jsonConfig = jsonConfig;
		return *this;
	}
	const std::string &getJsonConfig() const
	{
		return m_jsonConfig;
	}

	/**
	 * @brief	set a vertical exaggeration fro the shapefile
	 *
	 * @param	vertical exaggeration used in the shapefile
	 */
	OutputShapeParameters &verticalExaggeration(double verticalExaggeration)
	{
		m_verticalExaggeration = verticalExaggeration;
		return *this;
	}
	double getVerticalExaggeration() const
	{
		return m_verticalExaggeration;
	}

	/**
	 * @brief	set whether real world or profile coordinates will be used
	 *
	 * @param	the selection
	 *
	 * @note    this is only used for cross sections, default is real world
	 *          coordinates
	 */
	OutputShapeParameters &inProfileCoordinates(bool inProfileCoordinates)
	{
		m_inProfileCoordinates = inProfileCoordinates;
		return *this;
	}
	bool isInProfileCoordinates() const
	{
		return m_inProfileCoordinates;
	}
private:
	std::string m_outputPath;
	double m_verticalExaggeration;
	std::string m_title;
	std::string m_jsonConfig;
	bool m_inProfileCoordinates;
};
typedef boost::shared_ptr<OutputShapeParameters> OutputShapeParametersPtr;

/**
 * @brief	Sets the parameters for the resulting image
 */
class GST_API_EXPORT OutputImageParameters
{
public:
	/**
	 * @brief	Constructor.
	 *
	 * @param	outputPath  	Full pathname of the output file.
	 */
	OutputImageParameters(const std::string &outputPath);

	const std::string &getOutputPath() const { return mOutputPath; }

	/**
	 * @brief	Output image type.
	 *
	 * Set the type of the resulting image (SVG/PDF/PNG)
	 *
	 * @param	outputImageType	Type of the output image.
	 */
	OutputImageParameters &outputImageType(ImageType outputImageType);

	ImageType getOutputImageType() const { return mOutputImageType; }

	/**
	 * @brief	set a base64 encoded PNG as overview map
	 *
	 * @param	overviewMap	The overview map.
	 */
	OutputImageParameters &overviewMap(const std::string &overviewMap);

	const std::string &getOverviewMap() const { return mOverviewMap; }

	/**
	 * @brief	set a title for the image
	 *
	 * @param	title of the image
	 */
	OutputImageParameters &title(const std::string &title);

	const std::string &getTitle() const { return mTitle; }

	/**
	 * @brief	set template file
	 *
	 * @param	Full pathname of the template file
	 */
	OutputImageParameters &templateFile(
			const std::string &templateFile);

	const std::string &getTemplateFile() const { return mTemplateFile; }

	/**
	 * @brief	set a separate legend template file
	 *
	 * Overwrites legend parameters already defined in the standard
	 * template files
	 *
	 * @param	Full pathname of the legend template file
	 */
	OutputImageParameters &legendTemplateFile(
			const std::string &legendTemplateFile);

	const std::string &getLegendTemplateFile() const { return mLegendTemplateFile; }

	/**
	 * @brief	set additional output parameters (advanced)
	 * 			
	 * Overwrites all parameters set in the template files
	 *
	 * @param	parameters in the specified format
	 * 					   
	 * @todo    link to doc or something
	 */
	OutputImageParameters &additionalParameters(
			const std::string &additionalParameters);

	const std::string &getAdditionalParameters() const { return mParamsJson; }
private:
	ImageType mOutputImageType;
	std::string mTemplateFile;
	std::string mLegendTemplateFile;
	std::string mParamsJson;
	std::string mOutputPath;
	std::string mOverviewMap;
	std::string mTitle;
	int mDpi;
};
typedef boost::shared_ptr<OutputImageParameters> OutputImageParametersPtr;

class GST_API_EXPORT IntersectionGeometryParameters
{
public:
	IntersectionGeometryParameters(const std::string &intersectionGeometry,
								   const std::string &geometryFileType,
								   const Geometry::SRSPtr &geometrySrs);
	const std::string &getIntersectionGeometry() const;
	const std::string &getGeometryFileType() const;
	Geometry::SRSPtr getGeometrySrs() const;
	ZAxisDomain getZAxisDomain() const;
	/**
	 * @brief Glues together intersectionGeometry with json header
	 */
	std::string encodeIntersectionGeometry() const;

	IntersectionGeometryParameters &intersectionGeometry(
		const std::string &geometry);
	IntersectionGeometryParameters &zAxisDomain(ZAxisDomain zAxisDomain);

protected:
	friend class AbstractRDBAccess;
	friend class PGAccess;
	friend class OCCIAccess;
	friend class MSSQLAccess;
	std::string mIntersectionGeometry;
	std::string mGeometryFileType;
	Geometry::SRSPtr mGeometrySrs;
	ZAxisDomain mZAxisDomain;
};

class GST_API_EXPORT ImageParameters
	: public IntersectionGeometryParameters
{
public:
	ImageParameters(const std::string &featureList,
					const std::string &intersectionGeometry,
					const std::string &geometryFileType,
					const Geometry::SRSPtr &geometrySrs);

	ImageParameters(const MoMaKey &momakey,
					const std::string &intersectionGeometry,
					const std::string &geometryFileType,
					const Geometry::SRSPtr &geometrySrs);
	GST::ClientUtils::MoMaKey getMomakey() const;
	const std::string &getFeatureList() const;

	enum Mode
	{
		withMomaKey,
		withFeatureList
	};

	Mode getFeatureIdMode() const;

protected:
	friend class AbstractRDBAccess;
	friend class PGAccess;
	friend class OCCIAccess;
	friend class MSSQLAccess;
	MoMaKey mMomakey;
	std::string mFeatureList;
	Mode mMode;
};

/**
 * @brief	Sets the parameters for the virtual borehole
 */
class GST_API_EXPORT BoreHoleImageParameters : public ImageParameters
{
public:
	/**
	 * @brief	Constructor.
	 *
	 * @param	momakey					The momakey of the intersection
	 * 									features.
	 * @param	intersectionGeometry	The intersection geometry.
	 * @param	geometryFileType		The type of the geometry format
	 * 									(SFSP,GCD,etc.).
	 * @param	geometrySrs				The srs of the geometry.
	 */
	BoreHoleImageParameters(const MoMaKey &momakey,
							const std::string &intersectionGeometry,
							const std::string &geometryFileType,
							const Geometry::SRSPtr &geometrySrs);
	/**
	 * @brief	Constructor.
	 *
	 * @param	featureList				List of feature ids to intersect.
	 * @param	intersectionGeometry	The intersection geometry.
	 * @param	geometryFileType		The type of the geometry format
	 * 									(SFSP,GCD,etc.).
	 * @param	geometrySrs				The srs of the geometry.
	 */
	BoreHoleImageParameters(const std::string &featureList,
							const std::string &intersectionGeometry,
							const std::string &geometryFileType,
							const Geometry::SRSPtr &geometrySrs);
	/**
	 * @brief	Sets the dip of the borehole.
	 *
	 * @param	dip	The dip.
	 *
	 * @see		Dip
	 */
	BoreHoleImageParameters &dip(const Dip &dip);

	GST::ClientUtils::Dip getDip() const { return mDip; }

	/**
	 * @brief	Sets the azimuth of the borehole.
	 *
	 * @param	azimuth	The azimuth.
	 *
	 * @see		Azimuth
	 */
	BoreHoleImageParameters &azimuth(const Azimuth &azimuth);

	GST::ClientUtils::Azimuth getAzimuth() const { return mAzimuth; }

	/**
	 * @brief	Sets whether to project z or not
	 *
	 * If this is set to true, z will be projected onto the bounding box of the
	 * features selected with momakey.\n
	 * If this is set to false, z will be taken from the point defined in
	 * the intersectionGeometry.
	 *
	 * @param	projectZ	true or false
	 */
	BoreHoleImageParameters &projectZ(bool projectZ);

	bool getProjectZ() const { return mProjectZ; }

	/**
	 * @brief	Set the maximum bore depth.
	 *
	 * @param	maxBoreDepth	The maximum bore depth.
	 *
	 * @see		Distance
	 */
	BoreHoleImageParameters &maxBoreDepth(const Distance &maxBoreDepth);

	GST::ClientUtils::Distance getMaxBoreDepth() const { return mMaxBoreDepth; }

	/**
	 * @brief	Sets the property selection.
	 *
	 * @param	propertySelection	The property selection.
	 *
	 * @see		PropertySelection
	 */
	BoreHoleImageParameters &propertySelection(
			const PropertySelection &propertySelection);

	std::string getPropertySelection() const { return mPropertySelection.propertyName; }

	/**
	 * @brief	Sets the scale parameter of the intersection.
	 *
	 * @param	scaleParameter	The scale parameter.
	 *
	 * @see		ScaleParameter1D
	 */
	BoreHoleImageParameters &scaleParameter(
			const ScaleParameter1D &scaleParameter);

	GST::ClientUtils::ScaleParameter1D getScaleParameter() const { return mScaleParameter; }	

	/**
	 * @brief	Sets id of the dynamic color scale.
	 *
	 * @param	dynamicColorScaleId	The id parameter.
	 *
	 * @see		DynamicColorScale
	 */
	BoreHoleImageParameters &dynamicColorScaleId(
			const long &dynamicColorScaleId);

	long getDynamicColorScaleId() const { return mDynamicColorScaleId; }	
	

private:
	friend class AbstractRDBAccess;
	friend class PGAccess;
	friend class OCCIAccess;
	friend class MSSQLAccess;
	Dip mDip;
	Azimuth mAzimuth;
	bool mProjectZ;
	Distance mMaxBoreDepth;
	PropertySelection mPropertySelection;
	ScaleParameter1D mScaleParameter;
	long mDynamicColorScaleId;
};

/**
 * @brief	Sets the parameters for the cross section
 */
class GST_API_EXPORT SectionImageParameters : public ImageParameters
{
public:
	/**
	 * @brief	Constructor.
	 *
	 * @param	momakey					The momakey of the intersection
	 * 									features.
	 * @param	intersectionGeometry	The intersection geometry.
	 * @param	geometryFileType		The type of the geometry format
	 * 									(SFSP,GCD,etc.).
	 * @param	geometrySrs				The srs of the geometry.
	 */
	SectionImageParameters(const MoMaKey &momakey,
						   const std::string &intersectionGeometry,
						   const std::string &geometryFileType,
						   const Geometry::SRSPtr &geometrySrs);

	/**
	 * @brief	Constructor.
	 *
	 * @param	featureList				List of feature ids to intersect.
	 * @param	intersectionGeometry	The intersection geometry.
	 * @param	geometryFileType		The type of the geometry format
	 * 									(SFSP,GCD,etc.).
	 * @param	geometrySrs				The srs of the geometry.
	 */
	SectionImageParameters(const std::string &featureList,
						   const std::string &intersectionGeometry,
						   const std::string &geometryFileType,
						   const Geometry::SRSPtr &geometrySrs);
	/**
	 * @brief	Sets the property selection.
	 *
	 * @param	propertySelection	The property selection.
	 *
	 * @see		PropertySelection
	 */
	SectionImageParameters &propertySelection(
			const PropertySelection &propertySelection);

	std::string getPropertySelection() const { return mPropertySelection.propertyName; }

	/**
	 * @brief	Sets the depth range.
	 *
	 * @param	depthRange	The depth range.
	 *
	 * @see		DepthRange
	 */
	SectionImageParameters &depthRange(const DepthRange &depthRange);

	GST::ClientUtils::DepthRange getDepthRange() const { return mZrange; }

	/**
	 * @brief	Sets the scale parameter of the intersection.
	 *
	 * @param	scaleParameter	The scale parameter.
	 *
	 * @see		ScaleParameter2D
	 */
	SectionImageParameters &scaleParameter(
			const ScaleParameter2D &scaleParameter);

	GST::ClientUtils::ScaleParameter2D getScaleParameter() const { return mScaleParameter; }
	
	/**
	 * @brief	Sets the point projection distance.
	 *
	 * All points of point sets will be projected onto the intersection plane
	 * if they are closer than the pointProjectionDistance to the plane
	 *
	 * @param	distance	The distance.
	 *
	 * @see		Distance
	 */
	SectionImageParameters &pointProjectionDistance(const Distance &distance);

	GST::ClientUtils::Distance getPointProjectionDistance() const { return mPointProjectionDistance; }

	/**
	 * @brief	Sets id of the dynamic color scale.
	 *
	 * @param	dynamicColorScaleId	The id parameter.
	 *
	 * @see		DynamicColorScale
	 */
	SectionImageParameters &dynamicColorScaleId(
			const long &dynamicColorScaleId);

	long getDynamicColorScaleId() const { return mDynamicColorScaleId; }

private:
	friend class AbstractRDBAccess;
	friend class PGAccess;
	friend class OCCIAccess;
	friend class MSSQLAccess;
	DepthRange mZrange;		  	
	Distance mPointProjectionDistance;		
	PropertySelection mPropertySelection;	 	
	ScaleParameter2D mScaleParameter;	
	long mDynamicColorScaleId;
};

/**
 * @brief	Sets the parameters for the horizontal section
 */
class GST_API_EXPORT MapImageParameters : public ImageParameters
{
public:
	/**
	 * @brief	Constructor.
	 *
	 * @param	momakey					The momakey of the intersection
	 * 									features.
	 * @param	intersectionGeometry	The intersection geometry.
	 * @param	geometryFileType		The type of the geometry format
	 * 									(SFSP,GCD,etc.).
	 * @param	geometrySrs				The srs of the geometry.
	 */
	MapImageParameters(const MoMaKey &momakey,
					   const std::string &intersectionGeometry,
					   const std::string &geometryFileType,
					   const Geometry::SRSPtr &geometrySrs);
	/**
	 * @brief	Constructor.
	 *
	 * @param	featureList				List of feature ids to intersect.
	 * @param	intersectionGeometry	The intersection geometry.
	 * @param	geometryFileType		The type of the geometry format
	 * 									(SFSP,GCD,etc.).
	 * @param	geometrySrs				The srs of the geometry.
	 */
	MapImageParameters(const std::string &featureList,
					   const std::string &intersectionGeometry,
					   const std::string &geometryFileType,
					   const Geometry::SRSPtr &geometrySrs);

	/**
	 * @brief	Sets the property selection.
	 *
	 * @param	propertySelection	The property selection.
	 *
	 * @see		PropertySelection
	 */
	MapImageParameters &propertySelection(
			const PropertySelection &propertySelection);

	std::string getPropertySelection() const { return mPropertySelection.propertyName; }

	/**
	 * @brief	Sets the scale parameter of the intersection.
	 *
	 * @param	scaleParameter	The scale parameter.
	 *
	 * @see		ScaleParameter1D
	 */
	MapImageParameters &scaleParameter(const ScaleParameter1D &scaleParameter);

	GST::ClientUtils::ScaleParameter1D getScaleParameter() const { return mScaleParameter; }

	/**
	 * @brief	Sets the depth of the intersection plane
	 *
	 * This is the z value of the horizontal plane's height
	 *
	 * @param	depth	The depth.
	 */
	MapImageParameters &depth(double depth);

	double getDepth() const { return mDepth; }

	/**
	 * @brief	Sets the direction for the intersection area.
	 *
	 * The direction is defined as walking on the input line from the start
	 * to end the point. \n
	 *
	 * @image	html isec_area.png
	 *
	 * @param	direction	The direction (left or right).
	 *
	 * @see		MapImageDirection::Direction
	 * @see		MapImageParameters::distance
	 */
	MapImageParameters &direction(MapImageDirection::Direction direction);

	MapImageDirection::Direction getDirection() const { return mDirection; }

	/**
	 * @brief	Sets the distance for the intersection area.
	 *
	 * The distance along direction to define the intersection
	 * area.
	 *
	 * @image	html isec_area.png
	 *
	 * @param	distance	The distance.
	 *
	 * @see		Distance
	 * @see		MapImageParameters::direction
	 */
	MapImageParameters &distance(const Distance &distance);

	GST::ClientUtils::Distance getDistance() const { return mDistance; }

	/**
	 * @brief	Sets id of the dynamic color scale.
	 *
	 * @param	dynamicColorScaleId	The id parameter.
	 *
	 * @see		DynamicColorScale
	 */
	MapImageParameters &dynamicColorScaleId(
			const long &dynamicColorScaleId);

	long getDynamicColorScaleId() const { return mDynamicColorScaleId; }

private:
	friend class AbstractRDBAccess;
	friend class PGAccess;
	friend class OCCIAccess;
	friend class MSSQLAccess;
	double mDepth;
	Distance mDistance;
	MapImageDirection::Direction mDirection;
	PropertySelection mPropertySelection;
	ScaleParameter1D mScaleParameter;
	long mDynamicColorScaleId;
};

typedef boost::shared_ptr<BoreHoleImageParameters> BoreHoleImageParametersPtr;
typedef boost::shared_ptr<SectionImageParameters> SectionImageParametersPtr;
typedef boost::shared_ptr<MapImageParameters> MapImageParametersPtr;

class GST_API_EXPORT GridImageParameters
	: public IntersectionGeometryParameters
{
public:
	GridImageParameters(int64_t gridId,
						int64_t colorMapId,
						const std::string &intersectionGeometry,
						const std::string &geometryFileType,
						const Geometry::SRSPtr &geometrySrs);
	int64_t getGridId() const
	{
		return mGridId;
	}

	const int64_t &getColorMapId() const
	{
		return mColorMapId;
	}

protected:
	int64_t mGridId;
	int64_t mColorMapId;
};

/**
 * @brief	Sets the parameters for the grid virtual borehole
 */
class GST_API_EXPORT BoreholeGridImageParameters
	: public GridImageParameters
{
public:
	/**
	 * @brief	Constructor.
	 *
	 * @param	momakey					The momakey of the intersection
	 * 									features.
	 * @param	intersectionGeometry	The intersection geometry.
	 * @param	geometryFileType		The type of the geometry format
	 * 									(SFSP,GCD,etc.).
	 * @param	geometrySrs				The srs of the geometry.
	 */
	BoreholeGridImageParameters(int64_t gridId,
								int64_t colorMapId,
								const std::string &intersectionGeometry,
								const std::string &geometryFileType,
								const Geometry::SRSPtr &geometrySrs);
	/**
	 * @brief	Sets the dip of the borehole.
	 *
	 * @param	dip	The dip.
	 *
	 * @see		Dip
	 */
	BoreholeGridImageParameters &dip(const Dip &dip);

	GST::ClientUtils::Dip getDip() const
	{
		return mDip;
	}

	/**
	 * @brief	Sets the azimuth of the borehole.
	 *
	 * @param	azimuth	The azimuth.
	 *
	 * @see		Azimuth
	 */
	BoreholeGridImageParameters &azimuth(const Azimuth &azimuth);

	GST::ClientUtils::Azimuth getAzimuth() const
	{
		return mAzimuth;
	}

	/**
	 * @brief	Sets whether to project z or not
	 *
	 * If this is set to true, z will be projected onto the bounding box of the
	 * features selected with momakey.\n
	 * If this is set to false, z will be taken from the point defined in
	 * the intersectionGeometry.
	 *
	 * @param	projectZ	true or false
	 */
	BoreholeGridImageParameters &projectZ(bool projectZ);

	bool getProjectZ() const
	{
		return mProjectZ;
	}

	/**
	 * @brief	Set the maximum bore depth.
	 *
	 * @param	maxBoreDepth	The maximum bore depth.
	 *
	 * @see		Distance
	 */
	BoreholeGridImageParameters &maxBoreDepth(const Distance &maxBoreDepth);

	GST::ClientUtils::Distance getMaxBoreDepth() const
	{
		return mMaxBoreDepth;
	}

	/**
	 * @brief	Sets the scale parameter of the intersection.
	 *
	 * @param	scaleParameter	The scale parameter.
	 *
	 * @see		ScaleParameter1D
	 */
	BoreholeGridImageParameters &scaleParameter(
		const ScaleParameter1D &scaleParameter);

	GST::ClientUtils::ScaleParameter1D getScaleParameter() const
	{
		return mScaleParameter;
	}

private:
	Dip mDip;
	Azimuth mAzimuth;
	bool mProjectZ;
	Distance mMaxBoreDepth;
	ScaleParameter1D mScaleParameter;
};

/**
 * @brief	Sets the parameters for the grid cross section
 */
class GST_API_EXPORT SectionGridImageParameters
	: public GridImageParameters
{
public:
	/**
	 * @brief	Constructor.
	 *
	 * @param	momakey					The momakey of the intersection
	 * 									features.
	 * @param	intersectionGeometry	The intersection geometry.
	 * @param	geometryFileType		The type of the geometry format
	 * 									(SFSP,GCD,etc.).
	 * @param	geometrySrs				The srs of the geometry.
	 */
	SectionGridImageParameters(int64_t gridId,
							   int64_t colorMapId,
							   const std::string &intersectionGeometry,
							   const std::string &geometryFileType,
							   const Geometry::SRSPtr &geometrySrs);

	/**
	 * @brief	Sets the depth range.
	 *
	 * @param	depthRange	The depth range.
	 *
	 * @see		DepthRange
	 */
	SectionGridImageParameters &depthRange(const DepthRange &depthRange);

	GST::ClientUtils::DepthRange getDepthRange() const
	{
		return mZrange;
	}

	/**
	 * @brief	Sets the scale parameter of the intersection.
	 *
	 * @param	scaleParameter	The scale parameter.
	 *
	 * @see		ScaleParameter2D
	 */
	SectionGridImageParameters &scaleParameter(
		const ScaleParameter2D &scaleParameter);

	GST::ClientUtils::ScaleParameter2D getScaleParameter() const
	{
		return mScaleParameter;
	}

private:
	DepthRange mZrange;
	ScaleParameter2D mScaleParameter;
};

/**
 * @brief	Sets the parameters for the grid horizontal section
 */
class GST_API_EXPORT MapGridImageParameters : public GridImageParameters
{
public:
	/**
	 * @brief	Constructor.
	 *
	 * @param	momakey					The momakey of the intersection
	 * 									features.
	 * @param	intersectionGeometry	The intersection geometry.
	 * @param	geometryFileType		The type of the geometry format
	 * 									(SFSP,GCD,etc.).
	 * @param	geometrySrs				The srs of the geometry.
	 */
	MapGridImageParameters(int64_t gridId,
						   int64_t colorMapId,
						   const std::string &intersectionGeometry,
						   const std::string &geometryFileType,
						   const Geometry::SRSPtr &geometrySrs);

	/**
	 * @brief	Sets the scale parameter of the intersection.
	 *
	 * @param	scaleParameter	The scale parameter.
	 *
	 * @see		ScaleParameter1D
	 */
	MapGridImageParameters &scaleParameter(
		const ScaleParameter1D &scaleParameter);

	GST::ClientUtils::ScaleParameter1D getScaleParameter() const
	{
		return mScaleParameter;
	}

	/**
	 * @brief	Sets the depth of the intersection plane
	 *
	 * This is the z value of the horizontal plane's height
	 *
	 * @param	depth	The depth.
	 */
	MapGridImageParameters &depth(double depth);

	double getDepth() const
	{
		return mDepth;
	}

	/**
	 * @brief	Sets the direction for the intersection area.
	 *
	 * The direction is defined as walking on the input line from the start
	 * to end the point. \n
	 *
	 * @image	html isec_area.png
	 *
	 * @param	direction	The direction (left or right).
	 *
	 * @see		MapGridImageDirection::Direction
	 * @see		MapGridImageParameters::distance
	 */
	MapGridImageParameters &direction(MapImageDirection::Direction direction);

	MapImageDirection::Direction getDirection() const
	{
		return mDirection;
	}

	/**
	 * @brief	Sets the distance for the intersection area.
	 *
	 * The distance along direction to define the intersection
	 * area.
	 *
	 * @image	html isec_area.png
	 *
	 * @param	distance	The distance.
	 *
	 * @see		Distance
	 * @see		MapGridImageParameters::direction
	 */
	MapGridImageParameters &distance(const Distance &distance);

	GST::ClientUtils::Distance getDistance() const
	{
		return mDistance;
	}

private:
	double mDepth;
	Distance mDistance;
	MapImageDirection::Direction mDirection;
	ScaleParameter1D mScaleParameter;
};

/**
 * @brief	The maximum double value for the intersection parameters.
 */
extern const double maxDoubleValue;
} // namespace ClientUtils
} // namespace GST

#endif // GST_IntersectionParameters_h__